﻿
@implements IDisposable

<h1>Console cmd.exe</h1>

<p>
    OS:@Environment.OSVersion.Platform : @Environment.OSVersion
    <br />
    Dir : @Environment.CurrentDirectory
</p>

<BlazorDomTree OnRootReady="bdtready" />

@code
{
    System.Diagnostics.Process proc;
    bool _pagedisposed = false;
    void IDisposable.Dispose()
    {
        _pagedisposed = true;
        if (proc != null)
            proc.Kill();
        proc = null;
    }

    void bdtready(BlazorDomTree bdt)
    {
        System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo();
        psi.RedirectStandardInput = true;
        psi.RedirectStandardOutput = true;
        psi.RedirectStandardError = true;
        psi.FileName = "cmd.exe";
        proc = System.Diagnostics.Process.Start(psi);

        BlazorSession ses = BlazorSession.Current;


        PlusControl resultdiv = bdt.Root.Create("div style='margin:8px 0;height:400px;background-color:black;color:white;overflow-y:scroll;padding:5px 5px 15px;'");

        PlusControl div1 = bdt.Root.Create("div style='display:flex;'");
        // div1.Create("label style='width:100px").InnerText("Command:");
        PlusControl inpword = div1.Create("input type='text' style='flex:99;padding:0 5px'");
        PlusControl button = div1.Create("button").InnerText("Send");
        div1.Create("button").InnerText("^C").OnClick(delegate
        {
            if (inpword.Attribute_Disabled)
                return;
            proc.StandardInput.Write((byte)3);
            proc.StandardInput.Flush();
        });

        inpword.SetFocus(99);

        void SendLine(string line, string color)
        {
            var d = resultdiv.Create("div style='color:" + color + "'");
            if (string.IsNullOrEmpty(line))
                d.InnerHTML("<br />");
            else
                d.InnerText(line);
        }
        void ScrollBottom()
        {
            resultdiv.Eval("this.scrollTop=this.scrollHeight");
        }

        void SendCommand()
        {
            if (inpword.Attribute_Disabled)
                return;

            string cmdline = inpword.Value.Trim();
            if (cmdline.Length == 0)
            {
                BlazorSession.Current.Toast("type something");
                return;
            }

            inpword.Value = "";
            SendLine(cmdline, "yellow");

            ScrollBottom();

            proc.StandardInput.WriteLine(cmdline);
            proc.StandardInput.Flush();

        }

        inpword.OnEnterKey(delegate { SendCommand(); });
        button.OnClick(delegate { SendCommand(); });

        PlusControl div2 = bdt.Root.Create("div style='display:flex;'");

        List<string> cmds = new List<string>();
        cmds.Add("ls");
        cmds.Add("ps -ef|grep dotnet");

        foreach (string cmd in cmds)
        {
            div2.Create("button").InnerText(cmd).OnClick(delegate
            {
                if (inpword.Attribute_Disabled)
                    return;
                resultdiv.Create("div style='margin:1px;border-top:solid 1px white'");
                proc.StandardInput.WriteLine(cmd);
                proc.StandardInput.Flush();
            });
        }


        async Task ReadOutputAsync(BlazorSession ses)
        {
            try
            {
                while (true)
                {
                    string line = await proc.StandardOutput.ReadLineAsync();
                    if (line == null)
                        break;
                    ses.InvokeInRenderThread(delegate
                    {
                        SendLine(line, "");
                        ScrollBottom();
                    });
                }
            }
            catch (Exception x)
            {
                if (_pagedisposed)
                    return;
                ses.InvokeInRenderThread(delegate
                {
                    ses.Toast(x.ToString());
                });
            }
            finally
            {
                if (!_pagedisposed)
                {
                    ses.InvokeInRenderThread(delegate
                    {
                        inpword.Attribute_Disabled(true);
                        button.Attribute_Disabled(true);
                        if (proc.HasExited)
                        {
                            SendLine("cmd.exe exit", "yellow");
                        }
                        else
                        {
                            SendLine("Unknown error", "red");
                        }
                    });
                }
            }
        }

        var t1 = ReadOutputAsync(ses);

        async Task ReadErrorAsync(BlazorSession ses)
        {
            try
            {
                while (true)
                {
                    string line = await proc.StandardError.ReadLineAsync();
                    if (line == null)
                        break;
                    ses.InvokeInRenderThread(delegate
                    {
                        SendLine(line, "orange");
                        ScrollBottom();
                    });
                }
            }
            catch (Exception x)
            {
                if (_pagedisposed)
                    return;
                ses.InvokeInRenderThread(delegate
                {
                    ses.Toast(x.ToString());
                });
            }
        }

        var t2 = ReadErrorAsync(ses);
    }



}